package com.zodiac.alioth.web.security;

import com.zodiac.alioth.web.security.auth.AppAuthChecker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class AppAuthFilter implements Filter, InitializingBean {

    private static final Logger log = LoggerFactory.getLogger(AppAuthFilter.class);

    private AppAuthChecker appAuthChecker;

    private AppAuthChecker.Callback callback;

    private List<String> excludeUrlList = new ArrayList<>();

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    public AppAuthFilter() {

    }

    public AppAuthFilter(String... excludeUrlArray) {
        if (excludeUrlArray == null) {
            return;
        }
        excludeUrlList = Arrays.asList(excludeUrlArray);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        if (request instanceof HttpServletRequest) {
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            String requestURI = httpRequest.getRequestURI();
            if (isExclude(requestURI)) {
                chain.doFilter(request, response);
                return;
            }

            boolean check = appAuthChecker.check((HttpServletRequest) request, (HttpServletResponse) response);
            if (check) {
                chain.doFilter(request, response);
            }

        }

    }

    private boolean isExclude(String uri) {
        for (String pattern : excludeUrlList) {
            if (antPathMatcher.match(pattern, uri)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void destroy() {

    }

    public void setCallback(AppAuthChecker.Callback callback) {
        this.callback = callback;
    }

    public void setPageAuthChecker(AppAuthChecker starkAuthChecker) {
        this.appAuthChecker = starkAuthChecker;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (appAuthChecker == null) {
            appAuthChecker = new AppAuthChecker();
        }
        if (callback != null) {
            appAuthChecker.setCallback(callback);
        }
    }
}
